/*
 * @Author: wangshiyang
 * @Date: 2023-06-28 14:53:01
 * @LastEditors: wangshiyang
 * @LastEditTime: 2023-06-28 17:13:15
 * @Description: 添加obj模型
 *
 */
import * as THREE from "three";
import { OBJLoader } from "three/addons/loaders/OBJLoader.js";
import { MTLLoader } from "three/addons/loaders/MTLLoader.js";
import mapboxgl from "mapbox-gl";

class modelLoadHelper {
  constructor(map, options) {
    this.map = map;
    this.camera = new THREE.Camera();
    this.scene = new THREE.Scene();
    this.modelId = options.modelId ? options.modelId : "3dModel";
    this.modelOrigin = options.center ? options.center : [148.9819, -35.39847];
    this.modelHeight = options.height ? options.height : 0;
    this.modelAngle = options.angle ? options.angle : 0;
    this.modelScale = options.scale
      ? options.scale
      : {
          x: 1,
          y: 1,
          z: 1,
        };
    // 模型位置设置
    this.modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
      this.modelOrigin,
      this.modelHeight
    );
    this.objUrl = options.objUrl;
    this.mtlUrl = options.mtlUrl;
    this.modelLoaded = false;
    this.modelRoot = null;

    if (!this.objUrl) {
      console.warn("请输入obj模型的地址");
      return;
    }

    // 预加载模型
    this.preloadModel();
  }

  // 预加载模型
  preloadModel() {
    const mtlLoader = new MTLLoader();
    const objLoader = new OBJLoader();
    
    mtlLoader.load(this.mtlUrl, (mtl) => {
      mtl.preload();
      for (const material of Object.values(mtl.materials)) {
        material.side = THREE.DoubleSide;
        // 优化材质
        material.flatShading = true;
        material.needsUpdate = true;
      }
      objLoader.setMaterials(mtl);
      objLoader.load(this.objUrl, (root) => {
        this.modelRoot = root;
        this.modelLoaded = true;
        // 优化模型
        this.optimizeModel(root);
      });
    });
  }

  // 优化模型
  optimizeModel(model) {
    model.traverse((child) => {
      if (child instanceof THREE.Mesh) {
        // 优化几何体
        if (child.geometry) {
          child.geometry.computeVertexNormals();
          child.geometry.computeBoundingSphere();
          child.geometry.computeBoundingBox();
        }
        // 优化材质
        if (child.material) {
          child.material.flatShading = true;
          child.material.needsUpdate = true;
        }
      }
    });
  }

  addModel() {
    if (!this.modelLoaded) {
      console.warn("模型尚未加载完成");
      return;
    }

    const customLayer = {
      id: "3d-model",
      type: "custom",
      renderingMode: "3d",
      onAdd: function (map, gl) {
        // 优化光照
        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(0, -70, 100).normalize();
        this.scene.add(directionalLight);

        const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight2.position.set(0, 70, 100).normalize();
        this.scene.add(directionalLight2);

        const ambientLight = new THREE.AmbientLight(0xd3f53a, 0.5);
        this.scene.add(ambientLight);

        // 添加已加载的模型
        if (this.modelRoot) {
          this.scene.add(this.modelRoot);
        }

        this.map = map;
        this.renderer = new THREE.WebGLRenderer({
          canvas: map.getCanvas(),
          context: gl,
          antialias: true,
          alpha: true,
          powerPreference: 'high-performance'
        });
        this.renderer.autoClear = false;
      }.bind(this),
      render: function (gl, matrix) {
        // 优化渲染
        this.renderer.state.reset();
        this.renderer.render(this.scene, this.camera);
        this.map.triggerRepaint();
      }.bind(this)
    };

    this.map.addLayer(customLayer);
  }

  removeModel() {
    if (this.map.getLayer("3d-model")) {
      this.map.removeLayer("3d-model");
    }
  }
}

export default modelLoadHelper;
